package stock;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * Created by baoyunfeng on 2018/2/2.
 * <p>
 * <p>
 * 总金额
 * 当前资金总量 = coin购买时价值 + 持有资金总量
 * 卖出数据直接过滤买入数据，使持有数据数量始终为正
 */
public class PriceControl {

    //理想盈利率
    private static final float MENTAL_PROFIT_RATIO = 0.06f;
    //理想补仓率
    private static final float MENTAL_COVER_RATIO = 0.1f;

    private float mProfitRatio;
    private float mCoverRatio;
    private HoldModel mHoldModel;
    //现持有资金
    private float currentHoldCNTNumber;

    public static void main(String args[]) {
        PriceControl priceControl = new PriceControl();
        priceControl.setData(generateHoldModel());
        priceControl.run(0.0835f);
    }

    public PriceControl() {
        mProfitRatio = MENTAL_PROFIT_RATIO;
        mCoverRatio = MENTAL_COVER_RATIO;
    }


    public void setData(HoldModel mHoldModel){
        this.mHoldModel = mHoldModel;
        printBuyList();
    }


    public void run(float currentPrice) {
        System.out.println("------------当前价格:"+currentPrice+"-----------");
        analyzeStatus(currentPrice);
        analyzeBuy(currentPrice);
        analyzeSell(currentPrice);
        analyzeHint();
    }


    public static HoldModel generateHoldModel() {
        HoldModel holdModel = new HoldModel();
        holdModel.setName("swt");
        holdModel.setAllCNTNumber(2400);
//        holdModel.addStockModel(0.08f, 5000);
//        holdModel.addStockModel(0.0765f, 3000);
//        holdModel.addStockModel(0.074f, 3000);
//        holdModel.addStockModel(0.0786f, -5000);
//        holdModel.addStockModel(0.0806f, -6000);
        holdModel.addStockModel(0.08043f, 30000);
        holdModel.addStockModel(0.083f, -5000);
        holdModel.addStockModel(0.084f, 4950);
        holdModel.addStockModel(0.084f, -30000);
        holdModel.addStockModel(0.0846f, 29800);
//        holdModel.addStockModel(0.081f, -30000);
        return holdModel;
    }

    public void printBuyList() {
        if (mHoldModel == null) return;
        //当前资金总量
        float currentAllCNTNumber = mHoldModel.getAllCNTNumber() + calculateChangeResult();
        //当前持币价值人民币总量
        float currentCoinForCNTNumber = 0;
        //当前持币数量
        float currentCoinNumber = 0;
        float sellCoinOfCNT = 0;
        float buyCoinOfCNT = 0;
        Iterator<StockModel> iterator = calculateChangeList().iterator();
        while (iterator.hasNext()) {
            StockModel key = iterator.next();
            currentCoinNumber += key.getNumber();
            currentCoinForCNTNumber += key.getPrice() * key.getNumber();
            System.out.println(key.getPrice() + "=" + key.getNumber());
        }
        currentAllCNTNumber = currentAllCNTNumber - buyCoinOfCNT + sellCoinOfCNT;
        System.out.println("投资总资金：" + mHoldModel.getAllCNTNumber());
        System.out.println("当前资金总量：" + currentAllCNTNumber );
        currentHoldCNTNumber = currentAllCNTNumber - currentCoinForCNTNumber;
        System.out.println("剩余持有资金：" + currentHoldCNTNumber);
        System.out.println("当前Coin总量：" + currentCoinNumber);
        System.out.println("当前Coin均价：" + currentCoinForCNTNumber / currentCoinNumber);
    }

    public void analyzeStatus(float currentPrice) {
        int CNTnumber = 0;
        List<StockModel> list = calculateChangeList();
        for (int i = 0; i < list.size(); i++) {
            CNTnumber += (currentPrice - list.get(i).getPrice()) * list.get(i).getNumber();
        }
        System.out.println("当前浮盈为" + CNTnumber);
    }

    public void analyzeBuy(float currentPrice) {
        int numCount = 0;
        float tempCNTNumber = currentHoldCNTNumber;
        List<StockModel> stockModelList = calculateChangeList();
        for (int i = 0; i < stockModelList.size(); i++) {
            float stockPrice = stockModelList.get(i).getPrice();
            float stockNumber = stockModelList.get(i).getNumber();
            if (stockNumber < 0) {
                continue;
            }
            if (currentPrice < stockPrice * (1 - mCoverRatio)) {
                if (tempCNTNumber > stockNumber * currentPrice) {
                    numCount += stockNumber;
                    tempCNTNumber -= stockNumber * currentPrice;
                } else {
                    numCount += tempCNTNumber / currentPrice;
                }
            }
        }
        System.out.println("可以以价格为：" + currentPrice + "买入" + numCount);
    }

    public void analyzeSell(float currentPrice) {
        int numCount = 0;
        List<StockModel> stockModelList = calculateChangeList();
        for (int i = 0; i < stockModelList.size(); i++) {
            float stockPrice = stockModelList.get(i).getPrice();
            float stockNumber = stockModelList.get(i).getNumber();
            if (stockNumber < 0) {
                continue;
            }
            if (currentPrice > stockPrice * (1 + mProfitRatio)) {
                numCount += stockNumber;
            }
        }
        System.out.println("可以以价格为：" + currentPrice + "卖出" + numCount);
    }

//    public float getOperationNumber(float targetPrice,float buyPrice,float buyNumber){
//    }

    public void analyzeHint(){
        List<StockModel> stockModelList = calculateChangeList();
        System.out.println("------------建议买入价格:"+stockModelList.get(stockModelList.size()-1).getPrice()*(1 - mCoverRatio)+"-----------");
        System.out.println("------------建议卖出价格:"+stockModelList.get(0).getPrice()*(1 + mProfitRatio)+"-----------");
    }

    public float calculateChangeResult(){
        List<StockModel> sellStockModelList = mHoldModel.getSellStockList();
        List<StockModel> buyStockModelList = mHoldModel.getBuyStockList();


        float allSellNumber = 0;
        float allSellPrice = 0;
        for(int i = 0 ;i< sellStockModelList.size();i++){
            allSellNumber += sellStockModelList.get(i).getNumber();
            allSellPrice += sellStockModelList.get(i).getPrice() * sellStockModelList.get(i).getNumber();
        }



        float result = Math.abs(allSellPrice);
        float tempSellNumber = Math.abs(allSellNumber);
        for(int i = 0 ; i< buyStockModelList.size();i++){
            if(tempSellNumber<=0){
                break;
            }
            if(tempSellNumber>buyStockModelList.get(i).getNumber()){
                tempSellNumber -= buyStockModelList.get(i).getNumber();
                result -= buyStockModelList.get(i).getNumber() * buyStockModelList.get(i).getPrice();
            }else{
                result -= tempSellNumber * buyStockModelList.get(i).getPrice();
                tempSellNumber = 0;
            }
        }

        return result;
    }


    public List<StockModel> calculateChangeList(){
        List<StockModel> sellStockModelList = mHoldModel.getSellStockList();
        List<StockModel> buyStockModelList = mHoldModel.getBuyStockList();
        List<StockModel> stockModelList = new ArrayList<>();


        float allSellNumber = 0;
        float allSellPrice = 0;
        for(int i = 0 ;i< sellStockModelList.size();i++){
            allSellNumber += sellStockModelList.get(i).getNumber();
            allSellPrice += sellStockModelList.get(i).getPrice() * sellStockModelList.get(i).getNumber();
        }



        float result = Math.abs(allSellPrice);
        float tempSellNumber = Math.abs(allSellNumber);
        for(int i = buyStockModelList.size()-1 ; i>=0 ;i--){
            if(tempSellNumber>=0){
                if(tempSellNumber>buyStockModelList.get(i).getNumber()){
                    tempSellNumber -= buyStockModelList.get(i).getNumber();
                    result -= buyStockModelList.get(i).getNumber() * buyStockModelList.get(i).getPrice();
                }else{
                    float surplusNumber  = buyStockModelList.get(i).getNumber() - tempSellNumber;
                    result -= tempSellNumber * buyStockModelList.get(i).getPrice();
                    stockModelList.add(new StockModel(buyStockModelList.get(i).getPrice(),surplusNumber));
                    tempSellNumber= 0;
                }
            }else{
                stockModelList.add(new StockModel(buyStockModelList.get(i).getPrice(),buyStockModelList.get(i).getNumber()));
            }
        }

        return stockModelList;
    }

}


